package graphdao

import (
	"power/core/dao/table"
	"power/core/localwrap"
	"power/core/service/common"

	"github.com/RocksonZeta/wrap/redised"
	"github.com/RocksonZeta/wrap/utils/sutil"
	"github.com/RocksonZeta/wrap/utils/timeutil"
	"gopkg.in/guregu/null.v4"
)

const tableProject = "Project"
const tableProjectId = "Id"

var logProjects = localwrap.GetLogger().Fork("power/core/dao/graphdao", "Projects")

//Projects
type Projects struct {
	*redised.RedisedMysql
}

type ProjectsQueryParam struct {
	common.Page
	Name string
}

//Query 根据条件查询
func (s Projects) Query(param ProjectsQueryParam) ([]table.Project, int64) {
	logProjects.Debug().Func("Query").Interface("param", param).Send()
	wsql := " from Project where 1=1"
	if param.Name != "" {
		param.Name = "%" + param.Name + "%"
		wsql += " and name like :Name"
	}
	ssql := "select *" + wsql + " order by ct desc" + param.Limit()
	csql := "select count(*)" + wsql
	var r []table.Project
	s.Mysql.Select(&r, ssql, param)
	return r, s.Mysql.SelectInt(csql, param)
}

func (s Projects) Get(id int) table.Project {
	logProjects.Debug().Func("Get").Int("id", id).Send()
	var r table.Project
	s.RedisedMysql.Get(&r, tableProject, tableProjectId, id)
	return r
}

func (s Projects) List(ids []int) []table.Project {
	logProjects.Debug().Func("List").Ints("ids", ids).Send()
	var r []table.Project
	s.RedisedMysql.List(&r, tableProject, tableProjectId, ids)
	return r
}
func (s Projects) ListAsMap(ids []int) map[int]table.Project {
	logProjects.Debug().Func("ListAsMap").Ints("ids", ids).Send()
	l := s.List(ids)
	r := make(map[int]table.Project, len(l))
	for _, v := range l {
		r[v.Id] = v
	}
	return r
}

func (s Projects) Delete(id int) {
	logProjects.Debug().Func("Delete").Int("id", id).Send()
	old := s.Get(id)
	s.Mysql.Delete(tableProject, tableProjectId, id)
	s.ClearCache(old)
}

func (s Projects) ClearCache(old table.Project) {
	logProjects.Debug().Func("ClearCache").Int("id", old.Id).Send()
	s.Redis.Del(s.KeyFn(tableProject, old.Id))
	s.Redis.Del(s.KVFn(tableProject, map[string]interface{}{"graphId": old.GraphId}))
	s.Redis.Del(s.KVFn(tableProject, map[string]interface{}{"uid": old.Uid}))
}
func (s Projects) ListByGraphId(graphId int) []table.Project {
	logProjects.Debug().Func("ListByGraphId").Int("graphId", graphId).Send()
	var r []table.Project
	s.RedisedMysql.ListByKvs(&r, tableProject, tableProjectId, map[string]interface{}{"graphId": graphId})
	return r
}
func (s Projects) ListByUid(uid int) []table.Project {
	logProjects.Debug().Func("ListByUid").Int("uid", uid).Send()
	var r []table.Project
	s.RedisedMysql.ListByKvs(&r, tableProject, tableProjectId, map[string]interface{}{"uid": uid})
	return r
}

type ProjectsUpdateParam struct {
	Id             int
	Name           string
	GraphId        int
	State          int
	Uid            int
	BidDate        null.Time
	Manager        null.String
	ManagerPhone   null.String
	MapCenter      null.Int
	CompletionDate null.Time
	StaffNum       null.Int
	ProjectType    null.Int
	ProjectAddr    null.String
	Remark         null.String
}

func (s Projects) Update(param ProjectsUpdateParam) {
	logProjects.Debug().Func("Update").Interface("param", param).Send()
	s.Mysql.Patch(tableProject, tableProjectId, param)
	s.Redis.Del(s.KeyFn(tableProject, param.Id))
	// s.ClearCache(s.Get(param.Id)) if no index updated
}

type ProjectsAddParam struct {
	Name string
	//GraphId field:graphId int; normal index:pgraphId; fk:pgraphId ref:Graph.id设计图id
	GraphId int
	//State field:state int;项目状态
	State int
	//Uid field:uid int; normal index:puid; fk:puid ref:User.id创建者
	Uid int
	//MapCountry field:mapCountry varchar(2);地图国家，cn:中国
	MapCountry string
	//BidDate field:bidDate datetime;招标日期
	BidDate null.Time
	//Manager field:manager varchar(30);负责人
	Manager null.String
	//ManagerPhone field:managerPhone varchar(20);负责人电话
	ManagerPhone null.String
	//CompletionDate field:completionDate datetime;竣工日期
	CompletionDate null.Time
	//StaffNum field:staffNum int;人员规模
	StaffNum null.Int
	//ProjectType field:projectType int;项目类型
	ProjectType null.Int
	//ProjectAddr field:projectAddr varchar(200);项目地址
	ProjectAddr null.String
	//Remark field:remark varchar(300);备注
	Remark null.String
}

func (s Projects) Add(param ProjectsAddParam) table.Project {
	logProjects.Debug().Func("Add").Interface("param", param).Send()
	var t table.Project
	sutil.Copy(param, &t)
	t.Ct = timeutil.Now()
	s.Mysql.AddTable(t)
	s.Mysql.Insert(&t)
	s.ClearCache(t)
	return t
}
